﻿using System;
using System.IO;
using System.Web.Hosting;
using System.Xml;
using System.Xml.Serialization;
using System.Text;
using System.Linq;
using System.Collections.Generic;

namespace DotNetDream.Models
{
    public class SlideSubtitle
    {
        #region Constants
        public enum SaveSources
        {
            XML,
            Database,
            Auto
        }
        #endregion

        #region Properties
        public Subtitle Subtitle { get; set; }
        public string XMLRelativePath { get; set; }
        #endregion

        #region Helpers
        /// <summary>
        /// Load the data from an external XML file
        /// </summary>
        /// <param name="xmlPath"></param>
        private void loadFromFile(string xmlRelativePath)
        {
            try
            {
                XMLRelativePath = xmlRelativePath;
                string xmlPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, xmlRelativePath);
                using (XmlReader reader = XmlReader.Create(xmlPath))
                {
                    //Deserialize the file
                    XmlSerializer serializer = new XmlSerializer(typeof(Subtitle));
                    Subtitle = (Subtitle)serializer.Deserialize(reader);
                    //Init the item list if the XML file is empty
                    if (Subtitle.Items == null) Subtitle.Items = new SubtitleItem[0];
                }

            }
            catch (Exception ex)
            {
                //TODO: Log exception
                throw ex;
            }
        }

        /// <summary>
        /// Save the data to an extertal XML file
        /// </summary>
        /// <param name="xmlRelativePath"></param>
        private void saveToXML(string xmlRelativePath)
        {
            try
            {
                //Create the XML writer
                string xmlPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, xmlRelativePath);
                //Settings
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Encoding = Encoding.UTF8;
                settings.Indent = true;
                settings.IndentChars = "    ";
                //Blank namespaces
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("", "");

                using (XmlWriter writer = XmlWriter.Create(xmlPath, settings))
                {
                    //Serializer the object
                    XmlSerializer serializer = new XmlSerializer(typeof(Subtitle));
                    serializer.Serialize(writer, this.Subtitle, ns);
                }
            }
            catch (Exception ex)
            {
                //TODO: Log exception
                throw ex;
            }
        }


        /// <summary>
        /// Get the next available Id for a new subtitle item
        /// </summary>
        /// <returns></returns>
        private int getNextItemId()
        {
            return (Subtitle.Items.Length == 0) ? 1 : Subtitle.Items.Max(i => int.Parse(i.Id)) + 1;
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Constructor
        /// </summary>
        public SlideSubtitle(string xmlRelativePath)
        {
            Subtitle = new Subtitle();
            loadFromFile(xmlRelativePath);
        }
        #endregion

        #region Public Helpers
        /// <summary>
        /// Save current instance changes
        /// </summary>
        public void SaveChanges(SaveSources sources)
        {
            switch (sources)
            {
                case SaveSources.XML:
                    //To XML
                    saveToXML(XMLRelativePath);
                    break;
                case SaveSources.Database:
                    //To Database
                    throw new NotImplementedException();
                default:
                    //Default saving to XML
                    saveToXML(XMLRelativePath);
                    break;
            }
        }

        /// <summary>
        /// Update subtitle item
        /// </summary>
        /// <param name="id"></param>
        /// <param name="text"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        public void UpdateItem(string id, string text, string start, string end)
        {
            try
            {
                SubtitleItem item = Subtitle.Items.First(s => s.Id == id);
                item.Text = text;
                item.Start = start;
                item.End = end;
                //Then save to file
                SaveChanges(SaveSources.XML);
            }
            catch (Exception ex)
            {
                //TODO: Log exception
                throw ex;
            }
        }
        /// <summary>
        /// Delete subtitle item
        /// </summary>
        /// <param name="item"></param>
        public void DeleteItem(string id)
        {
            try
            {
                //Convert sub array to list
                List<SubtitleItem> temp = Subtitle.Items.ToList();
                //Remove the selected item
                temp.Remove(temp.AsEnumerable().First(s => s.Id == id));
                //Then rebind the sub collection
                Subtitle.Items = temp.ToArray();
                //Then save to file
                SaveChanges(SaveSources.XML);
            }
            catch (Exception ex)
            {
                //TODO: Log exception
                throw ex;
            }
        }

        /// <summary>
        /// Insert a subtitle
        /// </summary>
        /// <param name="text"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        public void InsertItem(string text, string start, string end)
        {
            try
            {
                //Created new item
                SubtitleItem item = new SubtitleItem();
                item.Id = getNextItemId().ToString();
                item.Text = text;
                item.Start = start;
                item.End = end;
                //Convert sub array to list
                List<SubtitleItem> temp = Subtitle.Items.ToList();
                //Add the new item
                temp.Add(item);
                //Then rebind the sub collection
                Subtitle.Items = temp.ToArray();
                //Then save to file
                SaveChanges(SaveSources.XML);
            }
            catch (Exception ex)
            {
                //TODO: Log exception
                throw ex;
            }
        }
        #endregion
    }
}